package clientset

import (
	"context"
	"gitverse.ru/synapse/kubelatte/pkg/api/v1alpha1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/watch"
	"k8s.io/client-go/kubernetes/scheme"
	"k8s.io/client-go/rest"
)

//go:generate go run github.com/vektra/mockery/v2@v2.20.2 --name=TriggerInstanceInterface
type TriggerInstanceInterface interface {
	List(ctx context.Context, ns string, opts metav1.ListOptions) (*v1alpha1.TriggerInstanceList, error)
	Get(ctx context.Context, ns string, name string, options metav1.GetOptions) (*v1alpha1.TriggerInstance, error)
	Update(ctx context.Context, ns string, triggerInstance *v1alpha1.TriggerInstance, opts metav1.UpdateOptions) (result *v1alpha1.TriggerInstance, err error)
	UpdateStatus(ctx context.Context, ns string, hostEntry *v1alpha1.TriggerInstance, opts metav1.UpdateOptions) (*v1alpha1.TriggerInstance, error)
	Create(ctx context.Context, ns string, triggerInstance *v1alpha1.TriggerInstance) (*v1alpha1.TriggerInstance, error)
	Delete(ctx context.Context, ns string, name string, opts metav1.DeleteOptions) error
	Watch(ctx context.Context, ns string, opts metav1.ListOptions) (watch.Interface, error)
}

type triggerInstanceClient struct {
	restClient rest.Interface
}

func (c *triggerInstanceClient) List(ctx context.Context, ns string, opts metav1.ListOptions) (*v1alpha1.TriggerInstanceList, error) {
	result := v1alpha1.TriggerInstanceList{}
	err := c.restClient.
		Get().
		Namespace(ns).
		Resource("triggerInstances").
		VersionedParams(&opts, scheme.ParameterCodec).
		Do(ctx).
		Into(&result)

	return &result, err
}

func (c *triggerInstanceClient) Get(ctx context.Context, ns string, name string, opts metav1.GetOptions) (*v1alpha1.TriggerInstance, error) {
	result := v1alpha1.TriggerInstance{}
	err := c.restClient.
		Get().
		Namespace(ns).
		Resource("triggerInstances").
		Name(name).
		VersionedParams(&opts, scheme.ParameterCodec).
		Do(ctx).
		Into(&result)

	return &result, err
}

func (c *triggerInstanceClient) Update(ctx context.Context, ns string, triggerInstance *v1alpha1.TriggerInstance, opts metav1.UpdateOptions) (result *v1alpha1.TriggerInstance, err error) {
	result = &v1alpha1.TriggerInstance{}
	err = c.restClient.Put().
		Namespace(ns).
		Resource("triggerInstances").
		Name(triggerInstance.Name).
		VersionedParams(&opts, scheme.ParameterCodec).
		Body(triggerInstance).
		Do(ctx).
		Into(result)
	return
}

func (c *triggerInstanceClient) UpdateStatus(ctx context.Context, ns string, hostEntry *v1alpha1.TriggerInstance, opts metav1.UpdateOptions) (result *v1alpha1.TriggerInstance, err error) {
	result = &v1alpha1.TriggerInstance{}
	err = c.restClient.Put().
		Namespace(ns).
		Resource("triggerInstances").
		Name(hostEntry.Name).
		SubResource("status").
		VersionedParams(&opts, scheme.ParameterCodec).
		Body(hostEntry).
		Do(ctx).
		Into(result)
	return
}

func (c *triggerInstanceClient) Create(ctx context.Context, ns string, triggerInstance *v1alpha1.TriggerInstance) (*v1alpha1.TriggerInstance, error) {
	result := v1alpha1.TriggerInstance{}
	err := c.restClient.
		Post().
		Namespace(ns).
		Resource("triggerInstances").
		Body(triggerInstance).
		Do(ctx).
		Into(&result)

	return &result, err
}

func (c *triggerInstanceClient) Delete(ctx context.Context, ns string, name string, opts metav1.DeleteOptions) error {
	return c.restClient.
		Delete().
		Namespace(ns).
		Resource("triggerInstances").
		Name(name).
		Body(&opts).
		Do(ctx).
		Error()
}

func (c *triggerInstanceClient) Watch(ctx context.Context, ns string, opts metav1.ListOptions) (watch.Interface, error) {
	opts.Watch = true
	return c.restClient.
		Get().
		Namespace(ns).
		Resource("triggerInstance").
		VersionedParams(&opts, scheme.ParameterCodec).
		Watch(ctx)
}
